/****************************************************************************
 * Copyright (C) 2012
 * by Dj_Skual
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you
 * must not claim that you wrote the original software. If you use
 * this software in a product, an acknowledgment in the product
 * documentation would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and
 * must not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 * distribution.
 *
 * TitleList.cpp
 *
 * for SaveGame Manager GX 2012
 ***************************************************************************/
#include <algorithm>

#include "../TextOperations/FreeTypeGX.h"
#include "../Themes/CTheme.h"
#include "../System/nandtitle.h"
#include "../XML/GameTDB.hpp"
#include "TitleList.hpp"

void TitleList::AddTitle()
{
	TitleStruct * newTitle = new TitleStruct;
	newTitle->ID = " ";
	newTitle->name = L" ";
	newTitle->tid = 0;
	
	titleList.push_back(newTitle);
}

std::string TitleList::GetID(int ind)
{
	if(ind < 0 || ind >= (int) titleList.size())
		return "";

	return titleList.at(ind)->ID;
}

std::wstring TitleList::GetName(int ind)
{
	if(ind < 0 || ind >= (int) titleList.size())
		return L"";

	return titleList.at(ind)->name;
}

u64 TitleList::GetTid(int ind)
{
	if(ind < 0 || ind >= (int) titleList.size())
		return 0;

	return titleList.at(ind)->tid;
}

void TitleList::Reset()
{
	for(u32 i = 0; i < titleList.size(); i++)
		delete titleList.at(i);

	titleList.clear();
}

static bool TitlesSortCallback(const TitleStruct *t1, const TitleStruct *t2)
{
	return (stricmp((wstr2str(((TitleStruct *)t1)->name)).c_str(), (wstr2str(((TitleStruct *)t2)->name)).c_str()) < 0);
}

int TitleList::Get()
{
	Reset();
	
	GameTDB * XML_DB = NULL;
	
	if(Settings.GameTDBTitles)
	{
		std::string gameTDBPath = Settings.GameTDBPath;
		gameTDBPath += "/wiitdb.xml";
		
		XML_DB = new GameTDB(gameTDBPath.c_str());
		XML_DB->SetLanguageCode(Settings.GameTDBLanguageCode);
	}
	
	NandTitles.Get();
	u32 n = NandTitles.SetType(0x10001);
	u32 cnt = 0;
	
	for (u32 i = 0; i < n; i++)
	{
		u64 tid = NandTitles.Next();
		if (!tid)
			break;
		
		if (!NandTitles.Exists(tid))
			continue;
		
		if(cnt >= titleList.size())
			AddTitle();
		
		char id[5];
		NandTitles.AsciiTID(tid, id);
		titleList.at(cnt)->ID = id;
		titleList.at(cnt)->tid = tid;
		
		std::wstring TitleName;
		bool needName = true;
		
		if(Settings.GameTDBTitles)
			needName = !XML_DB->GetTitle(id, TitleName);
		
		if(needName)
			TitleName = charToWideChar(NandTitles.NameOf(tid));
		
		if(!TitleName.empty())
			titleList.at(cnt)->name = TitleName;
		else
			titleList.at(cnt)->name = charToWideChar(tr("Unknown"));
		
		cnt++;
	}

	//! Get count of system titles
	n = NandTitles.SetType(0x10002);
	for (u32 i = 0; i < n; i++)
	{
		u64 tid = NandTitles.Next();
		if (!tid)
			break;
		
		//!these can't be booted anyways
		if (TITLE_LOWER( tid ) == 0x48414741 || TITLE_LOWER( tid ) == 0x48414141 || TITLE_LOWER( tid ) == 0x48414641)
			continue;
		
		//!these aren't installed on the nand
		if (!NandTitles.Exists(tid))
			continue;
		
		if(cnt >= titleList.size())
			AddTitle();
		
		char id[5];
		NandTitles.AsciiTID(tid, id);
		titleList.at(cnt)->ID = id;
		titleList.at(cnt)->tid = tid;
		
		std::wstring TitleName;
		bool needName = true;
		
		if(Settings.GameTDBTitles)
			needName = !XML_DB->GetTitle(id, TitleName);
		
		if(needName)
			TitleName = charToWideChar(NandTitles.NameOf(tid));
		
		if(!TitleName.empty())
			titleList.at(cnt)->name = TitleName;
		else
			titleList.at(cnt)->name = charToWideChar(tr("Unknown"));
		
		cnt++;
	}
	
	if(Settings.GameTDBTitles)
		delete XML_DB;
	
	if(titleList.size() > 1)
		std::sort(titleList.begin(), titleList.end(), TitlesSortCallback);

	if(!Settings.vWii)
	{
		if(cnt >= titleList.size())
			AddTitle();
		
		titleList.at(cnt)->tid = 0;
		titleList.at(cnt)->ID = " ";
		titleList.at(cnt)->name = charToWideChar(tr("Wii Settings"));
	}
	
	return titleList.size();
}
